package com.corejsf;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.inject.Inject;
import javax.inject.Named;
import javax.sql.DataSource;
// or import javax.faces.bean.ManagedBean;
import javax.annotation.Resource;
import javax.enterprise.context.SessionScoped;

// or import javax.faces.bean.SessionScoped;

@SuppressWarnings("serial")
@Named
@SessionScoped
/**
 * Menu only available to the superUser. Allows the superUser to add,
 * modify, create and delete users.
 * @author Jitin Dhillon, Kelton Kowalchuk
 *
 */
public class SuperMenu implements Serializable {
    /**
     * Used to import the datasource for SQL queries.
     */
	@Resource(mappedName = "java:jboss/datasources/worksheets")
	private static DataSource dataSource;
	/**
	 * Variable to store username for adding users.
	 */
	private String username;
	/**
     * Variable to store fullname for adding users.
     */
	private String fullname;
	/**
     * Variable to store password for adding users.
     */
	private String password;
	/**
     * Variable to store enumber for adding users.
     */
	private int enumber;
	/**
	 * Used to determine whether the "Usernames must be unique" error message.
	 */
	private boolean uniqueUsername;

	/**
	 * Login bean.
	 */
	@Inject	Login login;
	@Inject Credentials credentials;
	private ArrayList<User> temp = Credentials.users;
	
	/**
	 * Constructor for Supermenu.
	 */
	SuperMenu() {
	    uniqueUsername = true;
		checkUser();
	}
	
	/**
	 * Will set the activeUser to null and reset password and username fields.
	 * 
	 * @return navigation to the login page.
	 */
	public String logout() {
		login.setActiveUser(null);
		login.setPassword("");
		login.setPassword("");
		login.getConversation().end();
		return "login?faces-redirect=true";
	}

	/**
	 * Will delete a user from the system.
	 * @param user user to delete.
	 */
	public void delete(User user) {
		if (!user.isSuperUser()) {
			temp.remove(user);
			PreparedStatement stmt = null;
			Connection connection = null;
			try {
				try {
					connection = dataSource.getConnection();
					try {
						stmt = connection
								.prepareStatement("DELETE FROM users WHERE eNumber = ?");
						stmt.setInt(1, user.geteNumber());
						stmt.executeUpdate();
					} finally {
						if (stmt != null) {
							stmt.close();
						}
					}
				} finally {
					if (connection != null) {
						connection.close();
					}
				}
			} catch (SQLException ex) {
				System.out.println("Error in persist ");
				ex.printStackTrace();
			}
		}
	}

	/**
	 * Adds a user to the system.
	 */
	public String add() {
		String temp = "user";
		PreparedStatement stmt = null;
		Connection connection = null;
		int id = Credentials.getHighid();
		try {
			try {
				connection = dataSource.getConnection();
				try {
					stmt = connection
							.prepareStatement("INSERT INTO users VALUES(?, ?, ?, ?, ?)");
					stmt.setInt(1, id);
					stmt.setString(2, temp + id);
					stmt.setString(3, temp + id);
					stmt.setString(4, temp + id);
					stmt.setBoolean(5, false);
					stmt.executeUpdate();
				} finally {
					if (stmt != null) {
						stmt.close();
					}
				}
			} finally {
				if (connection != null) {
					connection.close();
				}
			}
		} catch (SQLException ex) {
			System.out.println("Error in persist ");
			ex.printStackTrace();
		}
		credentials.setIncrement();
		Credentials.getUsers();
		return "superMenu";
	}

	/**
	 * Save the changes made to the users list.
	 */
	public void save() {
	    uniqueUsername = true;
	    int count = 0;
	    for(User user : temp) {
	        for(User user2 : temp) {
	            if(user.getUsername().equals(user2.getUsername())) {
	                count++;
	            }
	        }
	        if(count > 1) {
	            uniqueUsername = false;
	            break;
	        }
	        count = 0;
	    }
	    if(uniqueUsername) {

    		for (User u : temp) {
    			PreparedStatement stmt = null;
    			Connection connection = null;
    			try {
    				try {
    					connection = dataSource.getConnection();
    					try {
    						stmt = connection
    								.prepareStatement("UPDATE users SET FullName = ?, UserName = ?, Password = ? WHERE eNumber = ?");
    						stmt.setString(1, u.getFullname());
    						stmt.setString(2, u.getUsername());
    						stmt.setString(3, u.getPassword());
    						stmt.setInt(4, u.geteNumber() );
    						stmt.executeUpdate();
    					} finally {
    						if (stmt != null) {
    							stmt.close();
    						}
    					}
    				} finally {
    					if (connection != null) {
    						connection.close();
    					}
    				}
    			} catch (SQLException ex) {
    				System.out.println("Error in persist ");
    				ex.printStackTrace();
    			}
    			u.setEditable(false);
    		}
    		Credentials.getUsers();
	    } else {
	        System.out.println("DUPLICATE USERNAMES");
	    }
	}
	
	/**
	 * Method to check whether the user is the superuser or regular user.
	 * @return the string for navigation rules.
	 */
	String checkUser() {
		if (!Login.getActiveUser().isSuperUser()) {
			return "login";
		} else
			return "superMenu";
	}
	
	public ArrayList<User> getTemp() { return temp; }
	public void setTemp(ArrayList<User> temp) {	this.temp = temp; }
	
	public Login getLogin() { return login;	}
	public void setLogin(Login login) { this.login = login;	}

	public String getUsername() { return username; }
	public void setUsername(String username) { this.username = username; }

	public String getFullname() { return fullname; }
	public void setFullname(String fullname) { this.fullname = fullname; }

	public String getPassword() { return password; }
	public void setPassword(String password) { this.password = password; }

	public int getEnumber() { return enumber; }
	public void setEnumber(int enumber) { this.enumber = enumber; }

    public boolean isUniqueUsername() { return uniqueUsername; }
    public void setUniqueUsername(boolean uniqueUsername) { this.uniqueUsername = uniqueUsername; }
}